package com.apes.hr.recruit.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.outbox.OutboxEventService;
import com.apes.framework.plugin.outbox.OutboxPayloadWrapper;
import com.apes.framework.plugin.outbox.OutboxSubscriberService;
import com.apes.framework.plugin.outbox.annotation.OutboxSubscriber;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.EventUtil;
import com.apes.framework.util.MapUtil;
import com.apes.hr.base.model.*;
import com.apes.hr.base.repository.EmployeeRepository;
import com.apes.hr.base.repository.StaffingRepository;
import com.apes.hr.base.repository.TransferRecordRepository;
import com.apes.hr.base.service.EmployeeService;
import com.apes.hr.base.service.StaffingService;
import com.apes.hr.group.model.DingDingPerson;
import com.apes.hr.group.repository.DingDingPersonRepository;
import com.apes.hr.recruit.model.ApplyJobOrder;
import com.apes.hr.recruit.model.RecruitOrder;
import com.apes.hr.recruit.repository.ApplyJobOrderRepository;
import com.apes.hr.recruit.repository.RecruitOrderRepository;
import com.apes.hr.thirdParty.dingidng.model.DingDingToken;
import com.apes.hr.thirdParty.dingidng.service.DingDingService;
import com.apes.hr.transfer.repository.QuitJobOrderRepository;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.party.model.Party;
import com.apes.scm.masterdata.party.model.PartyIdentification;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.model.Person;
import com.apes.scm.masterdata.party.repository.PartyIdentificationRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.party.service.PartyRoleService;
import com.apes.scm.masterdata.party.service.PartyService;
import com.apes.scm.rbac.model.Post;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.PostRepository;
import com.apes.scm.rbac.repository.UserRepository;
import com.apes.scm.rbac.service.UserService;
import com.dingtalk.api.request.OapiUserCreateRequest;
import com.dingtalk.api.response.OapiUserCreateResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 功能：应聘登记单
 *
 * @author HuJianLin
 * @create 2018-04-28 14:35
 */
@Service("hrApplyJobOrderService")
public class ApplyJobOrderService extends DomainService {
    @Autowired
    public ApplyJobOrderRepository applyJobOrderRepository;

    @Autowired
    public PartyService partyService;
    @Autowired
    public EmployeeRepository employeeRepository;
    @Autowired
    public StaffingRepository staffingRepository;
    @Autowired
    public StaffingService staffingService;
    @Autowired
    PartyIdentificationRepository partyIdentificationRepository;
    @Autowired
    EmployeeService employeeService;
    @Autowired
    EnumerationRepository enumerationRepository;
    @Autowired
    RecruitOrderRepository recruitOrderRepository;
    @Autowired
    TransferRecordRepository transferRecordRepository;
    @Autowired
    SequenceService sequenceService;
    @Autowired
    UserService userService;
    @Autowired
    PostRepository postRepository;
    @Autowired
    PartyRoleService partyRoleService;
    @Autowired
    UserRepository userRepository;
    @Autowired
    DingDingService dingService;
    @Autowired
    PartyRoleRepository partyRoleRepository;
    @Autowired
    DingDingToken dingDingToken;
    @Autowired
    DingDingPersonRepository dingDingPersonRepository;
    @Autowired
    QuitJobOrderRepository quitJobOrderRepository;

    /**
     * 检查数据判断，判读当前的输入版本信息
     * @param request
     */
    public void checkData(SimpleRequest request){
        String id = request.get("id");
        int version = request.get("version");

        if( request.get("staffing") == null ){
            throw new RuntimeException("人员编制不能为空!");
        }

        // 从数据库中取数，检查数据
        ApplyJobOrder applyJobOrder  = applyJobOrderRepository.findOne(id);
        if (applyJobOrder == null) throw new RuntimeException("应聘申请单【" + id + "】在系统中不存在。");
        if (applyJobOrder.getVersion() != version) throw new RuntimeException("记录已更新或已删除，请重新提交！");

    }

    /**
     * 检查入职人员的年龄
     * @param
     */
    private void checkAge(ApplyJobOrder applyJobOrder){
        if (applyJobOrder.getTalentPool()==null & applyJobOrder.getEmployee()==null)throw new RuntimeException("必须选择入职人员！");
        String idCard ;
        if (applyJobOrder.getTalentPool()!=null){
            idCard = applyJobOrder.getTalentPool().getIdCard();
        } else{
            idCard = applyJobOrder.getEmployee().getIdCard();
        }
        Employee emp = employeeRepository.findByIdCard(idCard);
        if (emp!=null) {
            if (emp.getEmployeeState() != null && emp.getEmployeeState().getId().equals("000088")) throw new RuntimeException("人员在职不予许重复入职！");
        }
        Integer personYear ;
        Integer personMonth;
        Integer personDay;
        if (idCard.length() == 18) {
            //截取身份证中出行人出生日期中的年、月、日
            personYear = Integer.parseInt(idCard.substring(6, 10));
            personMonth = Integer.parseInt(idCard.substring(10, 12));
            personDay = Integer.parseInt(idCard.substring(12, 14));
        } else{
            //截取身份证中出行人出生日期中的年、月、日
            personYear = Integer.parseInt("19"+idCard.substring(6, 8));
            personMonth = Integer.parseInt(idCard.substring(8, 10));
            personDay = Integer.parseInt(idCard.substring(10,12 ));
        }

        Calendar cal = Calendar.getInstance();
        // 得到当前时间的年、月、日
        Integer yearNow = cal.get(Calendar.YEAR);
        Integer monthNow = cal.get(Calendar.MONTH) + 1;
        Integer dayNow = cal.get(Calendar.DATE);

        // 用当前年月日减去生日年月日
        Integer yearMinus = yearNow - personYear;
        Integer monthMinus = monthNow - personMonth;
        Integer dayMinus = dayNow - personDay;

        Integer age = yearMinus; //先大致赋值

        if (yearMinus == 0) { //出生年份为当前年份
            age = 0;
        }else{ //出生年份大于当前年份
            if (monthMinus < 0) {//出生月份小于当前月份时，还没满周岁
                age = age - 1;
            }
            if (monthMinus == 0) {//当前月份为出生月份时，判断日期
                if (dayMinus < 0) {//出生日期小于当前月份时，没满周岁
                    age = age - 1;
                }
            }
        }
       if(age<16) throw new RuntimeException("此人员未满16周岁。不得入职");
    }

    /**
     * 功能：保存
     * @param request
     */
    public ApplyJobOrder save(SimpleRequest request)throws RuntimeException {

        ApplyJobOrder applyJobOrder = request.getO(ApplyJobOrder.class);
        applyJobOrder.setState("create");  //设置当前的状态
        if(applyJobOrder.getCreateDate() == null) {
            applyJobOrder.setCreateDate(new Date());
        }else {
            applyJobOrder.setUpdateDate(new Date());
        }
        this.checkAge(applyJobOrder);
        return applyJobOrderRepository.saveAndFlush(applyJobOrder);
    }

    /**
     * 功能：修改
     * @param request
     */
    public ApplyJobOrder update(SimpleRequest request)throws RuntimeException {

        ApplyJobOrder applyJobOrder = request.getO(ApplyJobOrder.class);
        this.checkAge(applyJobOrder);
        return applyJobOrderRepository.saveAndFlush(applyJobOrder);
    }

    /**
     * 功能：调整
     * @param request
     */
    public ApplyJobOrder adjust(SimpleRequest request)throws RuntimeException {
        ApplyJobOrder applyJobOrder = request.getO(ApplyJobOrder.class);
        Employee employee = applyJobOrder.getEmployee();
        // 将 employee 信息写入 Party
        Job job = applyJobOrder.getJob();

        employee.setPost(applyJobOrder.getWorkPost());
        employee.setRank(applyJobOrder.getRank());
        employee.setJob(job);
        employee.setCompany(applyJobOrder.getCompany());
        employee.setWorkBranch(applyJobOrder.getBranch());
        employee.setEmployeeState(enumerationRepository.findOne("000088"));//人员档案
        employee.setQuitState(null);//人员档案
        employee.setEntryDate(applyJobOrder.getFirstPayday());
        employee.setOrigin(employee.getId().substring(1,employee.getId().length()));
        if(applyJobOrder.getTestExaminer()!=null){
            employee.setTestExaminer(applyJobOrder.getTestExaminer());
        }
        employee.setOnDutyState(applyJobOrder.getOnDutyState());
        if (job.getName().indexOf("技工")!=-1){
            employee.setStaffShare(10);
        }else if(job.getName().indexOf("高级技师")!=-1){
            employee.setStaffShare(20);
        }else if(job.getName().indexOf("技师")!=-1){
            employee.setStaffShare(15);
        }else{
            employee.setStaffShare(10);
        }
        //人员档案没有生日
        if (employee.getBirthday() == null && employee.getIdCard() != null){
            Date birthday = idCardToBirthday(employee.getIdCard()); //使用身份证号码转换生日
            employee.setBirthday(birthday);
        }
        employeeService.adjustEmployee(employee);
        return applyJobOrderRepository.saveAndFlush(applyJobOrder);
    }

    /**
     * 功能：删除
     * @param request
     */
    public String delete(SimpleRequest request)throws RuntimeException {
        String id = request.get("id");
        ApplyJobOrder applyJobOrder = request.getO(ApplyJobOrder.class);
        if (applyJobOrder == null) throw new RuntimeException("入职申请：" + id + " 在系统中不存在。");
        applyJobOrder.setState("delete");
        applyJobOrder.setDeleteDate(new Date());
        applyJobOrderRepository.saveAndFlush(applyJobOrder);
        return "删除成功！";
    }
    /**
     * 功能：放弃 报道
     * @param request
     */
    public ApplyJobOrder cancelApply(SimpleRequest request)throws RuntimeException {
        String id = request.get("id");
        ApplyJobOrder applyJobOrder = request.getO(ApplyJobOrder.class);
        if (applyJobOrder == null) throw new RuntimeException("入职申请：" + id + " 在系统中不存在。");
        applyJobOrder.setState("cancel");
        applyJobOrder.setCancelDate(new Date());
        //小时工和临时工不修改人员编制
        if (!applyJobOrder.getJob().getId().equals("0013") && !applyJobOrder.getJob().getId().equals("0014")) {
            updateStaffing(applyJobOrder, false,-1);
        }
        Employee employee = applyJobOrder.getEmployee();
        employee.setCompany(applyJobOrder.getCompany());
        employee.setWorkBranch(applyJobOrder.getBranch());
        employee.setEmployeeState(enumerationRepository.findByTypeAndValue("放弃报道","employeeState"));//人员档案
        employeeService.createAndUpdate(employee);
        return applyJobOrderRepository.saveAndFlush(applyJobOrder);
    }
//    /**
//     * 功能：退回
//     * @param request
//     */
//    public ApplyJobOrder retreat(SimpleRequest request) throws RuntimeException {
//        ApplyJobOrder applyJobOrder = request.getO(ApplyJobOrder.class);
//        applyJobOrder.setState("retreat");
//        applyJobOrder.setReturnDate(new Date());
//        return applyJobOrderRepository.saveAndFlush(applyJobOrder);
//    }

    /**
     * 功能：审核
     * @param request
     */
    public ApplyJobOrder firstTrial(SimpleRequest request) throws RuntimeException {
        ApplyJobOrder applyJobOrder = request.getO(ApplyJobOrder.class);
        //小时工和临时工不修改人员编制
        if (!applyJobOrder.getJob().getId().equals("0013") && !applyJobOrder.getJob().getId().equals("0014")){
            updateStaffing(applyJobOrder, false,+1);
        }
        applyJobOrder.setState("firstTrial");
        applyJobOrder.setFirstTrialDate(new Date());
        Employee employee ;
        //同步后将employee关联到入职单
        if(applyJobOrder.getTalentPool()!=null){
            Employee emp = employeeRepository.findByIdCard(applyJobOrder.getTalentPool().getIdCard());
            if (emp!=null){
                if(emp.getEmployeeState()!=null && emp.getEmployeeState().getId().equals("000088")) throw new RuntimeException("人员在职不予许重复入职！");
                applyJobOrder.setTwoNdEntry(true);
            }
            employee = synTalentPoolToEmployee(applyJobOrder.getTalentPool());
            applyJobOrder.setEmployee(employee);
        }else{
            employee = applyJobOrder.getEmployee();
        }
        employee.setEmployeeState(enumerationRepository.findOne("000417"));//人员档案
        employee.setCompany(applyJobOrder.getCompany());
        employeeService.createAndUpdate(employee);
        return applyJobOrderRepository.saveAndFlush(applyJobOrder);
    }

    /**
     * 回填人员档案
     * @param employee
     * @param applyJobOrder
     */
    public Employee setEmployee(Employee employee ,ApplyJobOrder applyJobOrder){
        // 将 employee 信息写入 Party
        Job job = applyJobOrder.getJob();
        employee.setPost(applyJobOrder.getWorkPost());
        employee.setRank(applyJobOrder.getRank());
        employee.setJob(job);
        employee.setCompany(applyJobOrder.getCompany());
        employee.setWorkBranch(applyJobOrder.getBranch());
        employee.setEmployeeState(enumerationRepository.findOne("000088"));//人员档案
        employee.setQuitState(null);//人员档案
        employee.setEntryDate(applyJobOrder.getFirstPayday());
        employee.setOrigin(employee.getId().substring(1,employee.getId().length()));
        if(applyJobOrder.getTestExaminer()!=null){
            employee.setTestExaminer(applyJobOrder.getTestExaminer());
        }
        employee.setOnDutyState(applyJobOrder.getOnDutyState());
        if (job.getName().indexOf("技工")!=-1){
            employee.setStaffShare(10);
        }else if(job.getName().indexOf("高级技师")!=-1){
            employee.setStaffShare(20);
        }else if(job.getName().indexOf("技师")!=-1){
            employee.setStaffShare(15);
        }else{
            employee.setStaffShare(10);
        }
        //人员档案没有生日
        if (employee.getBirthday() == null && employee.getIdCard() != null){
            Date birthday = idCardToBirthday(employee.getIdCard()); //使用身份证号码转换生日
            employee.setBirthday(birthday);
        }
    return employeeService.createAndUpdate(employee);
    }

    @OutboxSubscriber(id = "local:ApplyJobOrderService.sendOutbox", name = "创建钉钉用户")
    private void sendOutbox(OutboxPayloadWrapper outboxPayloadWrapper){
        JSONObject param = JSONObject.parseObject(outboxPayloadWrapper.getPayload());
        String id = param.getString("id");
        ApplyJobOrder applyJobOrder = applyJobOrderRepository.findOne(id);
        createDingDingUser(applyJobOrder.getEmployee(),applyJobOrder,true);
    }

    /**
     * 添加钉钉用户
     * @param employee
     * @return
     * @throws
     */
    public String createDingDingUser(Employee employee,ApplyJobOrder applyJobOrder,boolean sign) {
        OapiUserCreateRequest request = new OapiUserCreateRequest();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

        JSONObject json = new JSONObject();
        json.put("生日",formatter.format(employee.getBirthday()));
        json.put("学历",applyJobOrder.getDegree().getDescription());

//        request.setUserid(employee.getOrigin());    //设置UserId为工号
        request.setName(employee.getName());        //设置姓名
        request.setMobile(employee.getMobileNumber());  //设置手机号码
        request.setHiredDate(employee.getEntryDate().getTime());    //设置入职时间时间戳（毫秒）
        request.setPosition(employee.getWorkBranch().getName() + "【" + employee.getPost().getName() + "】"); //设置职位 //21.04.14 使用工作部门加岗位名称组合
        request.setJobnumber(employee.getOrigin());     //设置工号
        request.setDepartment(Arrays.asList("1").toString());        request.setExtattr(json.toString());//附加信息

        OapiUserCreateResponse response = dingService.createUser(request,dingDingToken.getAccessToken());
        if (response.getErrcode()!=0){
            //为发出邀请报错并且不是事务发件箱推送时进入
            if (response.getErrcode() == 40103 && !sign) {
                // 发送事务发件箱
                OutboxPayloadWrapper outboxPayloadWrapper = new OutboxPayloadWrapper();
                outboxPayloadWrapper.setSubscriber("local:ApplyJobOrderService.sendOutbox");
                outboxPayloadWrapper.setAggregateId(applyJobOrder.getId());
                outboxPayloadWrapper.setPayload(new JSONObject(MapUtil.mapper("id", applyJobOrder.getId())).toJSONString());
                SpringManager.getBean(OutboxEventService.class).sendSaveEvent(outboxPayloadWrapper);
            }
            //不拦截同步手机号码在公司中已存在的报错
            if (response.getErrcode() != 60104){
                //要么是事务发件箱推送要么不是发出邀请报错时进入
                if(sign || response.getErrcode() != 40103) {
                    throw new RuntimeException("同步钉钉用户失败!" + response.getErrmsg());
                }
            }
        }
        //只有事务发件箱推送并且无报错时进入
        if(sign) {
            DingDingPerson dingDingPerson = dingDingPersonRepository.findByEmployee(employee);
            dingDingPerson.setDingDingUserId(response.getUserid());
        }
       return response.getUserid();
    }

    /**
     * 保存钉钉人员信息
     */
    public void saveDingDingPerson(Employee employee,ApplyJobOrder applyJobOrder,boolean sign){
        //根据人员档案和应聘申请单创建钉钉用户 sign:标记是否为事务发件箱推送
        String dingDingUser = createDingDingUser(employee, applyJobOrder,sign);
        //根据人员信息查找钉钉人员表
        DingDingPerson dingDingPerson = dingDingPersonRepository.findByEmployee(employee);
        //查到之前的更新钉钉ID把执行标识改成否
        if (dingDingPerson != null) {
            dingDingPerson.setDingDingUserId(dingDingUser);
            dingDingPerson.setExecute(false);
            dingDingPersonRepository.saveAndFlush(dingDingPerson);
        } else {
            //没有则创建
            DingDingPerson dingPerson = new DingDingPerson();
            dingPerson.setEmployee(employee);
            dingPerson.setDingDingUserId(dingDingUser);
            dingDingPersonRepository.saveAndFlush(dingPerson);
        }
    }

    /**
     * 功能：确认报道
     * @param request
     */
    public ApplyJobOrder done(SimpleRequest request) throws RuntimeException {
        ApplyJobOrder applyJobOrder = request.getO(ApplyJobOrder.class);
        Employee employee = applyJobOrder.getEmployee();
        employee = this.setEmployee(employee,applyJobOrder);
        updateRecruitOrder(applyJobOrder);  // 更新招聘单
        Party party = findParty(employee);
        employee.setParty(party);
        //钉钉添加用户(新)
        if(!applyJobOrder.getIsNeedDingDing()){
            //sign:标记是否为事务发件箱推送
            saveDingDingPerson(employee,applyJobOrder,false);
        }
        // 添加用户群组和考勤组
        SpringManager.getBean(OutboxSubscriberService.class)
                .commonSendRequest("local:hrDingDingDeptService.doneDingDing",
                        "doneDingDing" + new Date().getTime() , new JSONObject(MapUtil.mapper(
                                "id", applyJobOrder.getId()
                        )));
        //储备单上线后使用
        TalentPool talentPool = applyJobOrder.getTalentPool();
        if(talentPool!=null)talentPool.setApplyJob(true);
        //添加调动记录
        updateTransferRecord(applyJobOrder);
        User user = setUser(employee);
        //小时工和临时工不修改人员编制
        if (!applyJobOrder.getJob().getId().equals("0013") && !applyJobOrder.getJob().getId().equals("0014")) {
            updateStaffing(applyJobOrder, true, -1);
        }
        applyJobOrder.setState("done");
        applyJobOrder.setApproveDate(new Date());
        updateRecruitOrder(applyJobOrder);
        // 确定入职后 同步到 TMS系统 司机管理
        invoke("tms.chauffeur.createByApplyJobOrder", employee);
        return applyJobOrderRepository.saveAndFlush(applyJobOrder);

    }

    /**
     * 为入职人员添加操作员
     * @param employee
     * @return
     */
    public User setUser(Employee employee){
        User user = userRepository.findByOrigin(employee.getOrigin());
        List postLists = new JSONArray();
        postLists =  postRepository.findAllByBranchAndWorkPost(employee.getWorkBranch(), employee.getPost());
        if(user==null){
            // 没有 操作员的创建
            SimpleRequest request = new SimpleRequest();
            user = new User();
            user.setMobileNumber(employee.getMobileNumber());
            user.setName(employee.getName());
            user.setOrigin(employee.getOrigin());
            user.setPerson(partyRoleRepository.findByPartyIdAndRoleId(employee.getParty().getId(), "Employee"));
            user.setPosts(postLists);
            request.setData(user);
            user = userService.save(request);
        }else{
            user.setMobileNumber(employee.getMobileNumber());
            user.setPosts(null);
            user.setPosts(postLists);
            user.setDisable(false);
        }
        if (!synSaveUser(user))throw new RuntimeException("同步操作员失败!");
        return user;
    }


    /**
     * 更新招聘单
     * @param applyJobOrder
     */
    private void updateRecruitOrder(ApplyJobOrder applyJobOrder){
        RecruitOrder recruitOrder = applyJobOrder.getRecruitOrderId();
        if (recruitOrder==null) return;

        recruitOrder.setEntryQty(recruitOrder.getEntryQty()+1);
        if(recruitOrder.getEntryQty() == recruitOrder.getCurrentRecruitQty()){
            recruitOrder.setState("done");
            recruitOrder.setStopDate(new Date());
            recruitOrderRepository.saveAndFlush(recruitOrder);
        }
    }

    /**
     * 功能：同步数据到 旧框架
     * @param
     */
    private boolean synSaveEmployee(Employee employee)throws RuntimeException {
            //同步数据到 旧框架
            JSONObject setEmployee = new JSONObject();
            setEmployee.put("RYID",employee.getOrigin());
            setEmployee.put("RYMC",employee.getName());
            String oleBranch = employee.getWorkBranch().getOrigin();
            if(oleBranch!=null){
                setEmployee.put("Branch",oleBranch); //
            }else {
                throw new RuntimeException("同步数据到旧框架失败，无旧框架部门信息");
            }
            setEmployee.put("GW",employee.getPost().getName());//岗位名称
            setEmployee.put("GWID",employee.getPost().getId()); // 新旧系统 编码 将一致
            String sRYLX = ""; // RYLX	NUMBER(2)	人员类型(0:行政人员\仓管\收款员;1:采购业务员;2:销售业务员)
            String sBranchType = employee.getWorkBranch().getBranchType().getId();
            if(sBranchType.equals("000006")){ // 采购
                sRYLX = "1";
            }else if(sBranchType.equals("000007")){ // 销售
                sRYLX = "2";
            }else {
                sRYLX = "0";
            }
            setEmployee.put("RYLX",sRYLX);// 人员类型
            setEmployee.put("JOB", employee.getJob().getId());
            setEmployee.put("SJHM", employee.getMobileNumber());
            setEmployee.put("XB",employee.getSex().getDescription());
            setEmployee.put("FS",employee.getStaffShare());
            setEmployee.put("LRR","yyadmin");
            setEmployee.put("RYZT","4");//在职状态
//            String sZWJB = "";
//            if(employee.getRank()!=null){
//                sZWJB = employee.getRank().getName();
//            }
//            setEmployee.put("ZWJB",sZWJB);

            String topic = "event:hr.hrTransferSyn.saveEmployee";
            return (Boolean) EventUtil.sendSynEvent(this, topic, setEmployee).stream().findFirst().get();

    }

    /**
     * 同步user数据到 旧框架
     * @param user
     * @return
     */
    public boolean synSaveUser(User user){
        //同步数据到 旧框架
        JSONObject setUser = new JSONObject();
        StringBuffer sRoleList = new StringBuffer();  // 同步旧框架 使用
        setUser.put("RYID",user.getOrigin());
        setUser.put("RYMC",user.getName());
        setUser.put("CZYMM",user.getPassword());
        setUser.put("CZYLX",0);//操作员类型（0:内部员工；1：会员客户；2：供应商；3：线上；4：it服务商）
        setUser.put("CZYZT",0);//操作员状态（0：正常；1：注销；2：冻结）

        List<Post> postLists = user.getPosts();
        if (postLists.size()>0) {
            postLists.forEach(yRole -> {
                sRoleList.append(yRole.getOrigin() + ";");

            });
        }
        setUser.put("Roles",sRoleList);
        String topic = "event:hr.hrTransferSyn.synUser";
        return (Boolean) EventUtil.sendSynEvent(this, topic, setUser).stream().findFirst().get();
    }

    /**
     * 功能：更新 编制 信息
     * @param
     */
    private void updateStaffing(ApplyJobOrder applyJobOrder, Boolean realQtyAdd,int iDelayQty)throws RuntimeException {
        // 更新 编制 如无 增（一般情况不会无）
        List<Staffing> listStaffing = staffingRepository.findByBranchAndWorkPost(applyJobOrder.getBranch(), applyJobOrder.getWorkPost());
        Staffing staffing = new Staffing();
        int delayQty = 0;
        int realQty = 0;
        if (listStaffing.size() > 0) {
            staffing = listStaffing.get(0);
            realQty = staffing.getRealQty();
            delayQty = staffing.getDelayQty();
        } else {
            staffing.setCompany(applyJobOrder.getCompany());
            staffing.setBranch(applyJobOrder.getBranch());
            staffing.setWorkPost(applyJobOrder.getWorkPost());
        }
        if(realQtyAdd==true){
            realQty += 1;
        }
        delayQty = delayQty + iDelayQty;
        staffing.setDelayQty(delayQty);
        staffing.setRealQty(realQty);
        staffingService.create(staffing);
    }

    private Party findParty(Employee employee) throws RuntimeException {
        Party party = employee.getParty();
        if (party == null ){
            if(employee.getMobileNumber()!=null){
                PartyIdentification identification = partyIdentificationRepository.findFirstByPartyIdTypeAndIdValue("PIT_USCC", employee.getIdCard());
                PartyIdentification identificationMobile = partyIdentificationRepository.findFirstByPartyIdTypeAndIdValue("PIT_mobile", employee.getMobileNumber());
                //1.判断身份证当事人标识 2.判断手机当事人标识
                if(identification!=null){
                    party = identification.getParty();
                    PartyRole partyRole = partyRoleRepository.findByPartyIdAndRoleId(party.getId(),"Employee");
                    if(partyRole==null){
                        //party 为空时 并创建一个员工的partyRole.
                        party.addPartyRole("Employee",employee.getId().substring(1, employee.getId().length()));
                    }
                    if(identificationMobile != null){
                        if (identificationMobile.getParty() != party){
                            identificationMobile.setParty(party);
                            partyIdentificationRepository.saveAndFlush(identificationMobile);
                        }
                    } else {//没有手机号码为当事人标识时创建
                        PartyIdentification partyIdentification = new PartyIdentification();
                        partyIdentification.setParty(party);
                        partyIdentification.setPartyIdType("PIT_mobile");
                        partyIdentification.setIdValue(party.getPerson().getMobileNumber());
                        partyIdentificationRepository.saveAndFlush(partyIdentification);
                    }

                }else {//身份证标识为空 手机标识有
                    if(identificationMobile !=null){
//                        if(!party.getName().equals(employee.getName())){
//                            throw new RuntimeException("该员工与 "+party.getName()+" 手机号码重复,请确认是否同一个人!");
//                        } else {party = identificationMobile.getParty();}
                        party = identificationMobile.getParty();
                        PartyIdentification partyIdentification = new PartyIdentification();
                        partyIdentification.setParty(party);
                        partyIdentification.setPartyIdType("PIT_USCC");
                        partyIdentification.setIdValue(employee.getIdCard());
                        partyIdentificationRepository.saveAndFlush(partyIdentification);
                        Set<PartyRole> partyRoles= party.getPartyRoles();
                        partyRoles.forEach(partyRole -> {
                            if(partyRole.getRole().getId().equals("Employee")){
                                throw new RuntimeException("该入职员工的手机号码已被"+partyRole.getParty().getName()+"占用，到人员档案修改手机号码！");
                            }
                        });
                        party.setName(employee.getName());
                        party.setOrigin(employee.getId().substring(1, employee.getId().length()));
                        PartyRole partyRole = partyRoleRepository.findByPartyIdAndRoleId(party.getId(),"Employee");
                        if(partyRole==null){
                            //party 为空时 并创建一个员工的partyRole.
                            party.addPartyRole("Employee",employee.getId().substring(1, employee.getId().length()));
                        }
                    } else {
                        party = saveParty(employee);
                    }

                }

            }else{
                party = saveParty(employee);
            }
        }
        return party;
    }

    private Party saveParty(Employee employee){
        Party party = new Party();
        party.setPartyType("person");
        party.setName(employee.getName());
        party.setBank(employee.getBank());
        party.setBankAccount(employee.getBankAccount());
        // 处理 旧框架 对应 编码 统一
        String origin = employee.getId();
        origin = origin.substring(1, origin.length());
        party.setOrigin(origin);
      //  party.setOrigin(employee.getId());
        Person person = new Person();
        person.setSex(employee.getSex());
        person.setMobileNumber(employee.getMobileNumber());
        person.setBirthday(employee.getBirthday());
        person.setPostalAddress(employee.getPostalAddress());
        person.setIdCard(employee.getIdCard());
        person.setBank(employee.getBank());
        person.setBankAccount(employee.getBankAccount());
        person.setLivingCountry(employee.getRegCountry());
        person.setLivingProvince(employee.getLivingProvince());
        person.setLivingCity(employee.getLivingCity());
        person.setLivingCounty(employee.getLivingCounty());
        if(employee.getCompany()==null) throw new RuntimeException("请完善人员档案的所属公司！");
        person.setCompany(employee.getCompany().getParty());
        person.setWorkBranch(employee.getWorkBranch());
        person.setEmployeeState(employee.getEmployeeState());
        party.setPerson(person);
        // 返回 Party 数据 更新 employee
        party.addPartyRole("Employee",origin);
        return partyService.saveAndFlush(party,"Employee",origin);
    }

    public Page<ApplyJobOrder> findAll(SimpleRequest request) {
        List<Map> filters = request.get("condition");
        JSONObject djzt = new JSONObject();
        djzt.put("field","state");
        djzt.put("operator","NE");
        djzt.put("value","delete");
        filters.add(djzt);
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return applyJobOrderRepository.findAll(JpaDsl.toCriteria(filters),PageRequest.of(request.get("page"), request.get("size"),sort));
    }

    public ApplyJobOrder findOne(SimpleRequest request) {
        String id = request.get("id");
        ApplyJobOrder jobOrder = applyJobOrderRepository.findOne(id);
        if(jobOrder == null) throw new RuntimeException("入职申请单：" + id + " 在系统中不存在。");
        String state = jobOrder.getState();
        if(!state.equals("delete")){
            return jobOrder;
        }else {
            throw new RuntimeException("入职申请单：" + id + " 已删除。");
        }
    }

    public List<Map> findByEmployeeAndState(SimpleRequest request) {
        String id = request.get("employeeId");
        Employee employee = employeeRepository.findOne(id);
        List<ApplyJobOrder> jobOrders = applyJobOrderRepository.findByEmployee(employee).stream()
                .sorted(Comparator.comparing(ApplyJobOrder :: getCreateDate).reversed()).collect(Collectors.toList());
//        ApplyJobOrder applyJobOrder;
//        if(!jobOrders.isEmpty()){
//           applyJobOrder = jobOrders.stream().findFirst().get()
//            applyJobOrder=jobOrders.get(jobOrders.size()-1);
//            return applyJobOrder;
//        }else {
//            return null;
//        }
        List<Map> maps = new ArrayList<>();
        if (!jobOrders.isEmpty()){
            jobOrders.forEach(jobOrder -> {
                maps.add(MapUtil.mapper(
                        "id",jobOrder.getId(),
                        "createDate", DateUtil.format(jobOrder.getCreateDate(),DateUtil.SHOW_DATE_FORMAT)
                ));
            });
        }
        return maps;
    }

    public Map findFirstByEmployeeAndState(SimpleRequest request) {
        String id = request.get("employeeId");
        Employee employee = employeeRepository.findOne(id);
        List<ApplyJobOrder> jobOrders = applyJobOrderRepository.findByEmployee(employee).stream()
                .sorted(Comparator.comparing(ApplyJobOrder :: getCreateDate).reversed()).collect(Collectors.toList());

        List<Map> maps = new ArrayList<>();
        if (!jobOrders.isEmpty()){
            jobOrders.forEach(jobOrder -> {
                maps.add(MapUtil.mapper("jobOrders",jobOrder));
            });
            return maps.get(0);
        }
        return null;
    }

    //增加调动记录
    public void updateTransferRecord(ApplyJobOrder applyJobOrder){
        Employee employee = applyJobOrder.getEmployee();
        TransferRecord transferRecord = new TransferRecord();
        transferRecord.setEmployee(employee);
        transferRecord.setWorkBranch(employee.getWorkBranch());
        transferRecord.setPost(employee.getPost());
        transferRecord.setJob(employee.getJob());
        transferRecord.setRank(employee.getRank());
        transferRecord.setOnDutyState(employee.getOnDutyState());
        transferRecord.setTransferOn(applyJobOrder.getAgreeEntryDate());
        transferRecord.setEchelon(employee.isEchelon());
        transferRecord.setDriver(employee.isDriver());
        transferRecord.setValid(true);
        transferRecord.setApplyJobOrderId(applyJobOrder.getId());
        transferRecordRepository.saveAndFlush(transferRecord);
    }

    /**
     *  将人才储备数据同步到人员档案
     * @param employee
     * @param talentPool
     */
    public void setTalentPoolToEmployee(Employee employee , TalentPool talentPool){
        employee.setMobileNumber( talentPool.getMobileNumber()); //手机号
        employee.setTelephone(talentPool.getTelephone()); //固定电话
        employee.setMailAddress(talentPool.getMailAddress());//邮寄地址
        employee.setPostalAddress(talentPool.getPostalAddress());//通讯地址
        employee.setIdCardAddress(talentPool.getIdCardAddress()); //身份证地址
        employee.setQqNumber(talentPool.getQqNumber());//qq
        employee.setEmail( talentPool.getEmail())  ; //email
        employee.setSex( talentPool.getSex()); //性别
        employee.setBirthday(talentPool.getBirthday());//生日
        employee.setIdCard(talentPool.getIdCard());//身份证号
        employee.setWeight(talentPool.getWeight());//体重
        employee.setHeight(talentPool.getHeight()); //身高
        employee.setNativePlace(talentPool.getNativePlace());//籍贯
        employee.setCensusRegNature(talentPool.getCensusRegNature());//户口性质
        employee.setNation(talentPool.getNation()); //民族
        employee.setBloodType(talentPool.getBloodType()); //血型
        employee.setPoliticalVisage(talentPool.getPoliticalVisage());//政治面貌
        employee.setMaritalState(talentPool.getMaritalState());//婚姻状况
        employee.setDifferentWorks(talentPool.getDifferentWorks()); //可接受的异地工作地点
        employee.setTheOnlyChild(talentPool.isTheOnlyChild());//是否独生子女
        employee.setContact(talentPool.getContact());//紧急联系人
        employee.setContactPhone(talentPool.getContactPhone());//紧急联系人电话
        employee.setMandarinLevel(talentPool.getMandarinLevel());//普通话水平(skillProficiency)
        employee.setLocalDialectLevel(talentPool.getLocalDialectLevel()); //本地方言水平(skillProficiency)
        employee.setTypingSpeed(talentPool.getTypingSpeed());//打字速度
        employee.setIme(talentPool.getIme());//输入法
        employee.setSkilled(talentPool.isSkilled());//是否熟练驾驶
        employee.setEmployeeEducations(talentPool.getEmployeeEducations());//教育背景
        Set<EmployeeEducation> employeeEducations = talentPool.getEmployeeEducations();
        employeeEducations.forEach(employeeEducation -> {
            employeeEducation.setEmployee(employee);
        });
        employee.setEmployeeFamilies(talentPool.getEmployeeFamilies());//家庭成员
        talentPool.getEmployeeFamilies().forEach(employeeFamily -> {
            employeeFamily.setEmployee(employee);
        });
        employee.setEmployeeSkillCertificates(talentPool.getEmployeeSkillCertificates());// 技能 证书
        talentPool.getEmployeeSkillCertificates().forEach(employeeSkillCertificate -> {
            employeeSkillCertificate.setEmployee(employee);
        });
        employee.setEmployeeWorkHistories(talentPool.getEmployeeWorkHistories());//工作经历
        talentPool.getEmployeeWorkHistories().forEach(employeeWorkHistory -> {
            employeeWorkHistory.setEmployee(employee);
        });
        employee.setEnglishLevel(talentPool.getEnglishLevel()); //英语水平
        employee.setDriverLicenseType(talentPool.getDriverLicenseType());//驾照类型
        employee.setNameBefore(talentPool.getNameBefore()); //曾用名
        employee.setAge(talentPool.getAge());//年龄
        employee.setFertility(talentPool.getFertility());//生育状况
        employee.setContactRelation(talentPool.getContactRelation()); //和紧急联系人关系
        employee.setTitle(talentPool.getTitle()); //从业资格证、职称
        employee.setApplicationJob(talentPool.getApplicationJob());//应聘职位
        employee.setBasePay(talentPool.getBasePay()); //期望底薪
        employee.setMonthIncome(talentPool.getMonthIncome());//期望月收入
        employee.setAvailability(talentPool.getAvailability());//可到岗时间
        employee.setLiveDormitory(talentPool.isLiveDormitory());//需要住员工宿舍
        employee.setRecruitChannel(talentPool.getRecruitChannel());//招聘渠道
        employee.setNatureOfJob(talentPool.getNatureOfJob()); //职位性质
        employee.setStatement(talentPool.getStatement());  //声明内容
        employee.setSameTradeKeepOut(talentPool.isSameTradeKeepOut());//是否有签《竞争行业禁止协议》
        employee.setHasOtherJob(talentPool.isHasOtherJob());//是否与其他单位存在劳动关系
        employee.setCognitiveEmployeeE(talentPool.getCognitiveEmployee()); //推荐人
        employee.setCognitiveRelationE(talentPool.getCognitiveRelation()); //与推荐人的关系
        employee.setDevelopmentE(talentPool.getDevelopment());//发展规划
        if (StringUtils.isNotEmpty(talentPool.getChooseSocialSecurity())) {
            employee.setChooseSocialSecurity(talentPool.getChooseSocialSecurity());//购买社保意向
        }
        employee.setofficeSet(talentPool.getofficeSet());
        employee.setIdCardTerm(talentPool.getIdCardTerm()); //身份证到期时间
        employee.setDriver(talentPool.isDriver());  //是否有驾驶证
        employee.setDriverTerm(talentPool.getDriverTerm()); //驾驶证到期时间
//        employee.setOffice(talentPool.getOffice()); //办公软件
        if (!CollectionUtils.isEmpty(talentPool.getdesignSoftwareSet())) {
            employee.setdesignSoftwareSet(talentPool.getdesignSoftwareSet());
        }
//        employee.setDesignSoftware(talentPool.getDesignSoftware());  //设计软件
        if (!CollectionUtils.isEmpty(talentPool.getfunctionSet())) {
            employee.setFunctionsSet(talentPool.getfunctionSet());
        }
//        employee.setFunctions(talentPool.getFunctions());//常用函数
        if (!CollectionUtils.isEmpty(talentPool.getunacceptableSet())) {
            employee.setunacceptableSet(talentPool.getunacceptableSet());
        }
//        employee.setUnacceptables(talentPool.getUnacceptables());//不能接受的企业行为
        talentPool.isApplyJob();//是否已经入职

    }

    /**
     *  同步时判断有同名否（有同名加size）
     * @param employeeList
     * @param employee
     * @param talentPool
     */
    public void setEmployeeName(List<Employee> employeeList,Employee employee ,TalentPool talentPool){
        if (employeeList!=null && !employeeList.isEmpty()){
            String  name = String.valueOf(talentPool.getName() +(employeeList.size()+1));
            employee.setName(name);
        }else{
            employee.setName(talentPool.getName());
        }
    }

    /**
     * 字符串强制转换为数字
     * @param name
     * @return
     */
    private Boolean tryName(String name) {
        Boolean boo = false;
        if (!"".equals(name)) {
            char num[] = name.toCharArray();//把字符串转换为字符数组
            StringBuffer title = new StringBuffer();//使用StringBuffer类，把非数字放到title中
            StringBuffer hire = new StringBuffer();//把数字放到hire中
            if (Character.isDigit(num[num.length-1])) {//如果名字最后一位是数字为true ，否则 false
                boo = true;// 如果输入的是数字，把它赋给hire
            } else {
                boo = false;// 如果输入的是字符，把它赋给title
            }
        }
        return boo;
    }



    /**
     * 将人才储备库的人员信息同步到人员档案
     * @param talentPool
     */
    public Employee synTalentPoolToEmployee(TalentPool talentPool){
        Employee employee = employeeRepository.findByIdCard(talentPool.getIdCard());
        List<Employee> employeeList = employeeRepository.findByLikeName(talentPool.getName());
        List<Employee> employeeList2 = new ArrayList<>();

        employeeList.forEach(employee1 -> {
            String name = employee1.getName();

            if(name.equals(talentPool.getName()) ||tryName(name)){
                employeeList2.add(employee1);
            }
        });
        if (employee!=null){
            setTalentPoolToEmployee(employee,talentPool);
            employeeRepository.saveAndFlush(employee);
        } else {
            employee =  new Employee();
            String code = sequenceService.getId("PARTY_Employee" );
            employee.setId("0"+code);
            setEmployeeName(employeeList2,employee,talentPool);
            setTalentPoolToEmployee(employee,talentPool);
            employee = employeeRepository.saveAndFlush(employee);
        }
        talentPool.setEmployee(employee);
        return employee;

    }

    /**
     * date转localDate
     * @param date
     * @return
     */
    public static LocalDate DateToLocaleDate(Date date) {
        Instant instant = date.toInstant();
        ZoneId zoneId  = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDate();
    }

    /**
     * 找到个人最新的入职单
     * @param
     * @return
     */
    public ApplyJobOrder findByEmployee(Employee employee){
        List<ApplyJobOrder> applyJobOrderList = applyJobOrderRepository.findByEmployee(employee);
        List<ApplyJobOrder> quitList =new ArrayList<>();
        applyJobOrderList = applyJobOrderList.stream().filter(applyJobOrder -> applyJobOrder.getState().equals("done"))
                .sorted(Comparator.comparing(ApplyJobOrder::getAgreeEntryDate)).collect(Collectors.toList());//根据调入时间自然顺序;

        return applyJobOrderList.get(0);

    }

    /**
     * 使用身份证号码转换生日
     * @param idCard 身份证号码
     * @return 生日
     */
    public Date idCardToBirthday(String idCard){
        Date birthday = null;
        String year = idCard.substring(6,10);   //调用substring方法返回相关字段，注意索引从0开始
        String month = idCard.substring(10,12); //获取月份
        String day = idCard.substring(12,14);   //获取天数
        String temp = year + "-" + month + "-" + day;
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");//定义一个时间转换格式“年-月-日”
        try {     //捕获类型转换（解析）异常
            birthday = fmt.parse(temp); //1993-10-17
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return birthday;
    }

}
